/**
 * 执行fisp的一系列操作
 * 将静态资源上传到qiniu
 * 最后根据build.json文件内容上传到所有线上服务器
 * @type {exports}
 */

var tool = require("./tool"),
    mail = require("./mail"),
    upload2Cdn = require("./upload2Cdn"),
    onlineHelper = require("./push2OnlineHelper"),
    back2Prev = require("./back2Prev"),
    info, argvArr, prompt, buildInfo,
    deployInfo, access, username,
    json, res, pkg, uploads, imgs,
    fonts, moduleName;

module.exports = function (next) {
    require("colors");
    require("shelljs/global");
    prompt = require("prompt");

    argvArr = require("../config.js");
    buildInfo = argvArr[tool.findIn('s', argvArr, 'cmd')]["params"];
    deployInfo = require("../../deploy-conf.json");


    console.log("--------------------------上线质量及代码安全是程序员的红线!!!--------------------------".red);

    setTimeout(function () {
        if (exec("cd .build/build.json && git pull").code != 0) {
            console.log("\ngit pull error!".red);
            process.exit(0);
        } else {
            tool.log("your username: ".green);
            var execInfo = exec("whoami");

            if (execInfo.code == 0) {
                username = execInfo.output.replace("\n", "");
                info = require("../build.json/index.json");

                if (!buildInfo.length) {
                    buildInfo = info;
                }

                if (exec("fisp release -omp --domains -d " + tool.PREFIX_PATH).code != 0) {
                    console.error("Error: Fisp release to server faild!");
                } else {
                    moduleName = deployInfo.namespaces;
                    json = require(tool.PREFIX_PATH + "/config/" + moduleName + "-map.json");

                    res = tool.filterResources(json.res);
                    pkg = tool.filterResources(json.pkg);
                    imgs = tool.getAllFiles(tool.PREFIX_PATH + "/static/" + moduleName, /png|jpg|jpeg|gif/i) || [];
                    fonts = tool.getAllFiles(tool.PREFIX_PATH + "/static/" + moduleName + "/font", /woff|tff|eot|svg|woff2/i) || [];
                    uploads = [].concat(res, pkg, imgs, fonts);

                    if (info.access.indexOf(username) != -1) {
                        console.log("\nstatic file upload to cdn...".green);
                        upload2Cdn(uploads, function () {
                            if (info.previews && info.previews.length) {
                                sendPreviews(next);
                            } else {
                                sendServers(next);
                            }
                        });
                    } else {
                        console.log("you have no power to push to online!".red)
                    }
                }
            } else {
                console.log("get username faild!".red);
            }
        }
    }, 2000);
};

function sendPreviews(next) {
    var previewUrls = info.previews || [],
        onlineUrls = getOnlineList(),
        serverMap = [], serverArr = [];

    if (!("servers" in buildInfo)) {
        var sArr = onlineUrls.serverArr,
            sMap = onlineUrls.serverMap,
            tmp = [];

        for (var j = 0, length = sArr.length; j < length; j++) {
            var buildItem = sArr[j];
            for (var i = 0, len = previewUrls.length; i < len; i++) {
                if (previewUrls[i].link === buildItem) {
                    tmp.push(sMap[i]);
                    serverArr.push("preview" + i);
                }
            }
        }
        serverMap = tmp.concat();
    } else {
        serverMap = previewUrls.concat();
        serverArr = serverMap.map(function (item, index) {
            return "preview" + index;
        });
    }

    if (serverArr.length) {
        console.log("\n--------------------------预览机上线--------------------------".green);
        onlineHelper({
            serverMap: serverMap,
            serverArr: serverArr,
            username: username,
            modulename: moduleName
        }, function (postToDel) {
            prompt.start();
            prompt.get({
                properties: {
                    needBack: {
                        message: "请进行预览机验证，确认是否需要回滚(y/n)",
                        required: true
                    }
                }
            }, function (err, result) {
                if (result.needBack == "y") {
                    back2Prev(function () {
                        if (next && next.length) {
                            next.shift()(next);
                        }
                    }, null, previewUrls);
                } else {
                    postToDel(function () {
                        sendServers(next);
                    });
                }
            });
        });
    } else {
        postToDel(function () {
            sendServers(next);
        });
    }
}

function sendServers(next) {
    prompt.start();
    prompt.get({
        properties: {
            server: {
                message: "请确认是否需要进行全量上线操作(y/n)",
                required: true
            }
        }
    }, function (err, result) {
        if (result.server == "y") {
            var onlineList = getOnlineList();
            mail.sendMail({
                error: [],
                success: onlineList.serverMap.map(function (item) {
                    return {
                        url: item.receiver,
                        status: {
                            code: 0,
                            error: "online status"
                        }
                    }
                })
            }, function () {
                console.log("\n--------------------------全量上线--------------------------".green);

                onlineHelper({
                    serverMap: onlineList.serverMap,
                    serverArr: onlineList.serverArr,
                    username: username,
                    modulename: moduleName
                }, function (postToDel) {
                    prompt.start();
                    prompt.get({
                        properties: {
                            needBack: {
                                message: "请进行线上机器验证，确认是否需要回滚(y/n)",
                                required: true
                            }
                        }
                    }, function (err, result) {
                        if (result.needBack == "y") {
                            back2Prev(function () {
                                if (next && next.length) {
                                    next.shift()(next);
                                }
                            }, onlineList.serverMap, null);
                        } else {
                            postToDel(function () {
                                if (next && next.length) {
                                    next.shift()(next);
                                }
                            });
                        }
                    });
                    postToDel(function () {
                        if (next && next.length) {
                            next.shift()(next);
                        }
                    });
                });
            }, 0);
        }
    });
}

function getOnlineList() {
    var serverMap = [], serverArr = [];

    if ("servers" in buildInfo) {
        serverMap = buildInfo.servers.concat();
        serverArr = serverMap.map(function (item, index) {
            return "server" + index;
        });
    } else {
        for (var i = 0, len = info.servers.length; i < len; i++) {
            var buildItem = info.servers[i];
            for (var j = 0, length = buildInfo.length; j < length; j++) {
                var item = buildInfo[j];
                if (/^https?:\/\//ig.test(item)) {
                    if (buildItem.receiver.indexOf(item) != -1) {
                        serverArr.push("server" + i);
                        serverMap.push(buildItem);
                    }
                } else if (/^server(\d)+/ig.test(item) && RegExp["$1"] == i) {
                    serverArr.push("server" + i);
                    serverMap.push(buildItem);
                } else if (item == buildItem.group) {
                    serverArr.push("server" + i);
                    serverMap.push(buildItem);
                }
            }
        }
    }

    return {
        serverMap: serverMap,
        serverArr: serverArr
    }
}
